package factory_rebate

import (
	"context"
	"log"

	"shop-manager/internal/do"

	"github.com/samber/lo"
	"gorm.io/gorm"
)

//go:generate newc
type FactoryRebateRepo struct {
	db *gorm.DB
}

func (c *FactoryRebateRepo) CreateFactoryRebate(ctx context.Context, oneData *do.FactoryRebate) (int, error) {
	log.Printf("CreateFactoryRebate: %+v\n", oneData)
	if err := c.db.WithContext(ctx).Create(&oneData).Error; err != nil {
		return 0, err
	}
	return oneData.ID, nil
}

func (c *FactoryRebateRepo) UpdateFactoryRebate(ctx context.Context, oneData *do.FactoryRebate) error {
	origin := &do.FactoryRebate{}
	if err := c.db.WithContext(ctx).First(origin, oneData.ID).Error; err != nil {
		return err
	}

	// 更新可修改字段
	origin.Rebate = oneData.Rebate
	origin.ValidityStartTime = oneData.ValidityStartTime
	origin.ValidityEndTime = oneData.ValidityEndTime

	return c.db.WithContext(ctx).Save(&origin).Error
}

func (c *FactoryRebateRepo) DeleteFactoryRebate(ctx context.Context, id int) error {
	return c.db.WithContext(ctx).Delete(&do.FactoryRebate{}, id).Error
}

type ListFactoryRebateParam struct {
	Page     int
	PageSize int
	IDs      []int
	GoodsIDs []int
	Search   string // 品牌
	Sorts string
}

// 分页查询
func (repo *FactoryRebateRepo) ListFactoryRebate(ctx context.Context, param ListFactoryRebateParam) (listData []*do.FactoryRebate, total int64, err error) {
	if param.Page <= 0 {
		param.Page = 1
	}
	if param.PageSize == 0 { // -1 means no limit
		param.PageSize = do.DefaultPageSize
	}

	err = repo.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		// 使用DISTINCT避免多表连接导致的重复数据
		tx = tx.Model(&do.FactoryRebate{}).Select("DISTINCT fr.*").Table("factory_rebate AS fr")

		// 关联商品表
		// if len(param.GoodsIDs) > 0 {
			tx = tx.Joins("LEFT JOIN goods g ON g.id = fr.goods_id")
		// }
		if param.Search != "" { // goods => category => category_meta
		tx = tx.Joins(`LEFT JOIN category c ON c.id = g.category_id`)
		tx = tx.Joins(`LEFT JOIN category_meta m ON (
			(c.class_id = m.id AND m.category_type = ?) OR
			(c.level_id = m.id AND m.category_type = ?) OR
			(c.brand_id = m.id AND m.category_type = ?))`, do.CategoryType_Class, do.CategoryType_Level, do.CategoryType_Brand)
		// 添加搜索条件，匹配商品名称或分类元数据名称
		tx = tx.Where("g.name LIKE ? OR m.name LIKE ?", "%"+param.Search+"%", "%"+param.Search+"%")
	}

		// 过滤条件
		if len(param.IDs) > 0 {
			tx = tx.Where("fr.id IN ?", param.IDs)
		}
		if len(param.GoodsIDs) > 0 {
			tx = tx.Where("g.id IN ?", param.GoodsIDs)
		}

		// 查询总数
		err = tx.Count(&total).Error
		if err != nil {
			return err
		}

		// 排序
		if param.Sorts != "" {
			tx = tx.Order(param.Sorts)
		}

		// 分页查询
		offset := (param.Page - 1) * param.PageSize
		err = tx.
			Offset(offset).
			Limit(param.PageSize).
			Find(&listData).Error
		if err != nil {
			return err
		}

		// 获取关联的商品信息
		goodsIDs := lo.Map(listData, func(item *do.FactoryRebate, index int) int {
			return item.GoodsID
		})

		goodsMap := make(map[int]*do.Goods)
		if len(goodsIDs) > 0 {
			var goodsList []*do.Goods
			if err := repo.db.WithContext(ctx).
				Where("id IN ?", goodsIDs).
				Find(&goodsList).Error; err != nil {
				return err
			}

			for _, goods := range goodsList {
				goodsMap[goods.ID] = goods
			}
		}

		return nil
	})

	return listData, total, err
}

func (repo *FactoryRebateRepo) GetFactoryRebate(ctx context.Context, id int) (*do.FactoryRebate, error) {
	rebate := &do.FactoryRebate{}
	if err := repo.db.WithContext(ctx).
		Preload("Goods").
		First(rebate, id).Error; err != nil {
		return nil, err
	}
	return rebate, nil
}

// 根据商品ID获取返点设置
func (repo *FactoryRebateRepo) GetRebatesByGoodsID(ctx context.Context, goodsID int) ([]*do.FactoryRebate, error) {
	var rebates []*do.FactoryRebate
	if err := repo.db.WithContext(ctx).
		Where("goods_id = ?", goodsID).
		Order("updated_at DESC").
		Find(&rebates).Error; err != nil {
		return nil, err
	}
	return rebates, nil
}

// BatchUpdateRebates 批量更新或创建返点记录
func (repo *FactoryRebateRepo) BatchUpdateRebates(ctx context.Context, goodsIDs []int, rebate float32, validityStartTime, validityEndTime string) error {
	// 使用事务处理批量操作
	return repo.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		for _, goodsID := range goodsIDs {
			// 检查是否存在返点记录
			var existingRebate do.FactoryRebate
			result := tx.Where("goods_id = ?", goodsID).First(&existingRebate)
			
			if result.Error == nil {
				// 存在则更新
				existingRebate.Rebate = rebate
				existingRebate.ValidityStartTime = validityStartTime
				existingRebate.ValidityEndTime = validityEndTime
				if err := tx.Save(&existingRebate).Error; err != nil {
					return err
				}
			} else if result.Error == gorm.ErrRecordNotFound {
				// 不存在则创建
				newRebate := &do.FactoryRebate{
					GoodsID:           goodsID,
					Rebate:            rebate,
					ValidityStartTime: validityStartTime,
					ValidityEndTime:   validityEndTime,
				}
				if err := tx.Create(newRebate).Error; err != nil {
					return err
				}
			} else {
				// 其他数据库错误
				return result.Error
			}
		}
		return nil
	})
}
